package cn.maihe.elg.operation.supports.bank;

import cn.maihe.elg.operation.config.XibBankConfig;
import cn.maihe.elg.operation.model.dto.BaseReq;
import cn.maihe.elg.operation.model.dto.BaseResp;
import cn.maihe.elg.operation.supports.bank.dto.*;
import cn.maihe.elg.operation.supports.bank.enums.SpdbMethod;
import cn.maihe.elg.operation.supports.bank.enums.XibMethod;
import cn.maihe.elg.operation.supports.system.ElgResourceService;
import cn.maihe.elg.operation.utils.ElgLogger;
import cn.maihe.elg.operation.utils.IdGenerate;
import com.alibaba.fastjson.JSON;
import com.open.sdk.OpenSDK;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * @Description 接口统一识别码 OPC103100201000300008900
 * 调用方法 GET
 * 编码格式 UTF-8
 * 报文体格式 URL参数
 * 测试环境URL https://etest4.spdb.com.cn/spdb/uat/api/fundDeposits/eDeposits/accountDetails
 * 生产环境URL https://api.spdb.com.cn/spdb/prd/api/fundDeposits/eDeposits/accountDetails
 * 旧版URL
 * 调用方法：POST
 * 测试：https://etest4.spdb.com.cn/spdb/uat/api/fundDeposits/eDeposits/accountDetails/post
 * 生产：https://api.spdb.com.cn/spdb/prd/api/fundDeposits/eDeposits/accountDetails/post
 * 必输标识 Y或M：必须填写的域；
 * C：某条件成立时必须填写的域；
 * N或O：可选填写的域。
 * 接入方式 全报文加密
 * @Author Alan
 * @Date 2024/08/30
 */
@Service
@Slf4j
public abstract class BaseXibBankTransService<REQ extends BaseReq, RESP extends BaseResp> {

    protected Class<REQ> reqClass;
    protected Class<RESP> respClass;

    @Resource
    protected XibBankConfig xibBankConfig;
    @Resource
    protected ElgResourceService elgResourceService;

    public BaseXibBankTransService() {
        Type[] types = ((ParameterizedType) (getClass().getGenericSuperclass())).getActualTypeArguments();
        this.reqClass = (Class<REQ>) types[0];
        this.respClass = (Class<RESP>) types[1];
    }

    @PostConstruct
    public void init() {
       /* ElgLogger.info(log, l -> l.info("厦门国际银行参数初始化:{}", xibBankConfig.getConfigPath()));
        OpenSDK.init(xibBankConfig.getConfigPath(), xibBankConfig.getDbPrivateKey());*/
    }

    protected abstract SpdbMethod spdbMethod();
    protected abstract XibMethod xibMethod();

//    protected String buildURL() {
//        return String.format("%s/%s", spdBankConfig.getSpdBaseApiUrl(), spdbMethod().getPathUri());
//    }

//    protected RESP sendSPDBApi(REQ req) {
//        String traceId = IdGenerate.genTranceId();
//        //请求参数校验
//        ValidateUtil.validate(req);
//        //序列化对象
//        String requestBody = JSON.toJSONString(req);
//
//        String clientId = spdBankConfig.getXSpdbClientId();
//        String secret = spdBankConfig.getXSpdbClientSecret();
//        String privatekey = spdBankConfig.getZtSm2PriKey();
//        String spdbPublicKey = spdBankConfig.getSpdSm2PubKey();
//        String method = spdbMethod().getMethodName();
//        String url = this.buildURL();
//        Boolean forbidden = spdbMethod().getForbidden() != null ? spdbMethod().getForbidden() : spdBankConfig.getForbidden();
//        Boolean encryption = spdbMethod().getEncryption() != null ? spdbMethod().getEncryption() : spdBankConfig.getEncryption();
//
//        try {
//            ElgLogger.info(log, l -> l.info("{} >> {} 请求地址:{}", traceId, spdbMethod(), buildURL()));
//            ElgLogger.info(log, l -> l.info("{} >> {} 请求报文:{}", traceId, spdbMethod(), requestBody));
//            ApiResponse apiResponse = SPDBSMEncryptor.requestApi(clientId, secret, privatekey, spdbPublicKey, method, url, requestBody, forbidden, encryption);
//            Assert.notNull(apiResponse, () -> "浦发响应报文为空");
//            ElgLogger.info(log, l -> l.info("{} << {} 响应报文:{}", traceId, spdbMethod(), JSON.toJSONString(apiResponse)));
//
//            SpdbRespCode spdbRespCode = SpdbRespCode.resolve(apiResponse.getCode());
//            if (spdbRespCode != SpdbRespCode.SUCCESS) {
//                throw new RuntimeException("响应码非正常[" + apiResponse.getCode()+ "]");
//            }
//            if (apiResponse.getVerify() == null || !apiResponse.getVerify()) {
//                throw new RuntimeException("响应验签失败[" + apiResponse.getVerify() + "]");
//            }
//
//            String decryptBody = apiResponse.getDecryptBody();
//            Assert.hasText(decryptBody, () -> "响应解密报文为空");
//
//            RESP resp = JSON.parseObject(decryptBody, this.respClass);
//
//            return resp;
//        } catch (Exception e) {
//            ElgLogger.error(log, l -> l.error("{} << {} 请求响应异常:{}", traceId, spdbMethod(), e.getMessage(), e));
//            throw new RuntimeException("处理异常:" + e.getMessage());
//        }
//    }

    public REQ toReq(Object obj) {
        return JSON.parseObject(JSON.toJSONBytes(obj), this.reqClass);
    }

//    public String encryt(String originalData, String randomKey, String privateKey, String appId, String publicKey){
//        String reqJson = CommonSecurityService.encryptData(originalData,randomKey,privateKey,appId,publicKey);
//        return reqJson;
//    }

    public XibAccountDetailRespDTO sendXibData(XibAccountDetailReqDTO req) {
        String traceId = IdGenerate.genTranceId();
        XibAccountDetailRespDTO accountDetailRespDTO = new XibAccountDetailRespDTO();
        try {
            String data = JSON.toJSONString(req.getClearBody());
            String response = OpenSDK.sendData(xibBankConfig.getPdId(), xibBankConfig.getApiId(), data);
            Assert.notNull(response, () -> "厦门国际响应报文为空");
//            System.out.println("response===" + response);
            accountDetailRespDTO = JSON.parseObject(response, XibAccountDetailRespDTO.class);
            String respCode = accountDetailRespDTO.getHead().getResponseCode();
            String respMsg = accountDetailRespDTO.getHead().getResponseMessage();
            ElgLogger.info(log, l -> l.info("{} << {} 厦门国际响应报文原文:{}", traceId, xibMethod(), response));
            if (!"00000".equals(respCode)) {
                throw new RuntimeException("厦门国际响应文头 respCode:" + respCode + " respMsg:" + respMsg);
            }
        } catch (Exception e) {
            ElgLogger.error(log, l -> l.error("{} << {} 请求响应异常:{}", traceId, spdbMethod(), e.getMessage(), e));
            throw new RuntimeException("处理异常:" + e.getMessage());
        }
        return accountDetailRespDTO;
    }

    @Test
    public void openSDKTest() throws Exception {
        String privateKey = "ANMNzr5tmnUsufjET6yotnNKU/nAvzidG7OKoE6GaTcj";
        String path = this.getClass().getClassLoader().getResource("config/config-dev.properties").getPath();
        OpenSDK.init(path, privateKey);
        String pdId = "ZHFW0002";   //产品ID ZF]S0004
        String apiId = "OPXM0001A201000700000100";  //接口ID
        String data = "{\"pageNo\":1,\"transTimeEnd\":\"20240827212700\",\"pageSize\":50,\"custAcct\":\"8005100000017168\",\"transTimeStart\":\"20240827000000\"}";
        OpenSDK.sendData(pdId,apiId,data);
    }
}
